﻿define([
    'Wjs/ui/elements/View',
    'Wjs/ui/widgets/tools/Collapser'
],
function (View) {
    'use strict';

    var TreeNodeHeader,
        TreeNode,
        Tree = Wjs.typeBuilder.define({

        onBeforeTypeDefined: function () {

            TreeNodeHeader = Wjs.typeBuilder.define({

                type: 'TreeNodeHeader',

                base: View,

                construct: function (conf, parent) {
                    var me = this;

                    conf = conf || {};

                    TreeNodeHeader.base.constructor.call(me, conf, parent);

                    me.tag = 'li';
                    me.addClass('w-tree-node-header');

                    if (conf.branch) { // Branch
                        // Set the expanded/collapsed icon classes
                        me.collapsedIconClass = conf.collapsedIconClass || 'w-tree-collapsed-icon';
                        me.expandedIconClass = conf.expandedIconClass || 'w-tree-expanded-icon';

                        if (conf.expanded) {
                            conf.iconClass = me.expandedIconClass;
                        }
                        else {
                            conf.iconClass = me.collapsedIconClass;
                        }

                        // Create the collapser tool
                        me.collapser = me.createChild({
                            collapsed: !conf.expanded,
                            onCollapse: function () {

                                me.replaceClass(me.expandedIconClass, me.collapsedIconClass);

                                if (parentWidget && parentWidget.onCollapse) {
                                    parentWidget.onCollapse.call(parentWidget);
                                }
                            },
                            onExpand: function () {

                                me.replaceClass(me.collapsedIconClass, me.expandedIconClass);

                                if (parentWidget && parentWidget.onExpand) {
                                    parentWidget.onExpand.call(parentWidget);
                                }
                            }
                        },
                            me.defaultCollapserType || 'collapser');
                    }
                    else { // Leaf
                        me.iconClass = conf.iconClass || 'w-tree-leaf-icon';
                    }

                    // Create the content
                    me.content = me.createChild(conf, me.defaultContentType || 'View');
                    me.content.addClass('w-inline-block');
                }
            });

            TreeNode = Wjs.typeBuilder.define({

                type: 'TreeNode',

                base: View,

                construct: function (conf, parent) {
                    var me = this,
                        headerConf = {};
                    conf = conf || {};

                    TreeNode.base.constructor.call(me, conf, parent);

                    me.tag = 'ul';
                    me.addClass('w-tree-node');

                    conf.items = conf.items || []; // A node is supposed to always have children

                    // Create the header
                    if (conf.header) {

                        if (Wjs.types.isString(conf.header)) {
                            headerConf = {
                                html: conf.header
                            };
                        }
                        else {
                            headerConf = conf.header;
                        }
                    }

                    headerConf.branch = true; // Flag the header as of a branch type
                    me.header = me.createChild(headerConf, me.defaultHeaderType || 'treeNodeHeader');

                    // Create the body
                    me.body = me.createChild({
                        items: conf.items,
                        defaultChildType: 'treeNode'
                    },
                        me.defaultBodyType || 'View');
                    me.body.addClass('wjs-tree-body');
                },

                defaultChildType: function (childConf) {
                    // To diferentiate between leaf and branch nodes the items property is used.
                    // Even if the branch is empty, an empty nodes: [] must be provided in order to make it a branch
                    if (childConf.items) {
                        return 'treeNode';
                    }
                    else {
                        return 'treeNodeHeader';
                    }
                },

                // Adds a node node to this one
                appendNode: function (node) {
                    //                    var me = this,
                    //                        type = childTypeSelector(node);

                    //                    this.children = this.children || [];

                    //                    if (!node.created) { // Create the node
                    //                        node = this.createWidget(node, type, this.owner);
                    //                    }

                    //                    if (this.main.dom) { // It is already rendered
                    //                        node.render(this.container.main.dom);
                    //                    }

                    //                    this.children.push(node);
                }
            });
        },

        type: 'Tree',

        base: View,

        construct: function (conf, parent) {
            var me = this;
            conf = conf || {};

            Tree.base.constructor.call(me, conf, parent);
            me.addClass('w-tree');

            // Create the loader
            if (conf.loader) {
                me.loader = typeManager.create(conf.loader, 'Loader');
            }

            // Root
            me.root = me.createChild(conf.root, me.defaultRootType || 'treeNode');

            // Assign the event handlers
            me.onCollapse = conf.onCollapse;
            me.onExpand = conf.onExpand;

            if (conf.selector) {
                me.selector = typeManager.create(conf.selector, 'itemSelector');
            }
        },

        selectable: true,

        appendNode: function (node) {
            this.root.appendNode(node);
        }
    });

    return Tree;
});